//
// Created by user on 20-3-14.
//

#ifndef _GATE_H_
#define _GATE_H_

/*========================  宏定义变量区  ==========================*/

/**
 * 这个宏函数是利用汇编语言把属性组装好，然后在通过输出部分把数据写到地址里面
 */
#define _set_gate(gate_selector_addr, type, ist, selector, code_addr)        \
do                                                                \
{    unsigned long __d0,__d1;                                    \
    __asm__ __volatile__    (    "movw	%%dx,	%%ax	\n\t"    \
                                "xorq	%%rcx,	%%rcx	\n\t"    \
                                "andq	$0x7,	%%rcx	\n\t"    \
                                "addq	%4,	    %%rcx	\n\t"    \
                                "shlq	$32,	%%rcx	\n\t"    \
                                "addq	%%rcx,	%%rax	\n\t"    \
                                "xorq	%%rcx,	%%rcx	\n\t"    \
                                "movl	%%edx,	%%ecx	\n\t"    \
                                "shrq	$16,	%%rcx	\n\t"    \
                                "shlq	$48,	%%rcx	\n\t"    \
                                "addq	%%rcx,	%%rax	\n\t"    \
                                "movq	%%rax,	%0	    \n\t"    \
                                "shrq	$32,	%%rdx	\n\t"    \
                                "movq	%%rdx,	%1	    \n\t"    \
                                :"=m"(*((unsigned long *)(gate_selector_addr)))    ,                    \
                                 "=m"(*(1 + (unsigned long *)(gate_selector_addr))),"=&a"(__d0),"=&d"(__d1)        \
                                :"i"(type << 8),                                    \
                                 "3"((unsigned long *)(code_addr)),"2"(selector),"c"(ist)                \
                                :"memory"        \
                            );                \
}while(0)

/**
 * 加载TR寄存器
 */
#define loadTR(n)                                \
do{                                                \
    __asm__ __volatile__(    "ltr	%%ax"        \
                            :                    \
                            :"a"(n << 3)        \
                            :"memory");            \
}while(0)

/*========================  结构体声明区  ==========================*/

/**
 * GDT 描述符结构体
 */
struct desc_struct {
    unsigned char x[8];
};

/**
 * IDT 门描述符结构体
 */
struct gate_struct {
    unsigned char x[16];
};

/*========================  变量声明区  ==========================*/

// GDT 表
extern struct desc_struct GDT_TABLE[];

// IDT 表
extern struct gate_struct IDT_TABLE[];

// 任务段
//extern unsigned int TSS64_TABLE[26];

/*========================  函数声明区  ==========================*/

/**
 * 设置中断门
 * @param n 序号
 * @param ist 64位
 * @param addr 处理函数地址
 */
void set_intr_gate(unsigned int n, unsigned char ist, void *addr);

/**
 * 设置陷阱门
 * @param n 序号
 * @param ist 当前描述符特权级
 * @param addr 处理函数地址
 */
void set_trap_gate(unsigned int n, unsigned char ist, void *addr);

/**
 * 设置系统调用门
 * @param n 序号
 * @param ist 当前描述符特权级
 * @param addr 处理函数地址
 */
void set_system_gate(unsigned int n, unsigned char ist, void *addr);

void set_reserve_gate(unsigned int n, unsigned char ist, void *addr);

/**
 * 设置TSS段描述符
 * @param n 序号
 * @param addr 处理函数地址
 */
void setTSSDescriptor(unsigned int n, void *addr);

void setTSS64(unsigned long rsp0, unsigned long rsp1, unsigned long rsp2, unsigned long ist1, unsigned long ist2,
              unsigned long ist3,
              unsigned long ist4, unsigned long ist5, unsigned long ist6, unsigned long ist7);

#endif //_GATE_H_